package com.ums.scumspay.service.impl;

import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ums.scumspay.constant.MerInfoConstant;
import com.ums.scumspay.constant.PayOrderNoConstant;
import com.ums.scumspay.constant.UrlConstant;
import com.ums.scumspay.entity.PayOrder;
import com.ums.scumspay.entity.req.b2c.BtoCPayReq;
import com.ums.scumspay.entity.req.b2c.ExtraReq;
import com.ums.scumspay.entity.req.b2c.PosReq;
import com.ums.scumspay.entity.req.b2c.TransDataReq;
import com.ums.scumspay.service.BtoCService;
import com.ums.scumspay.service.PayOrderService;
import com.ums.scumspay.utils.CounterSignUtils;
import com.ums.scumspay.utils.RandomUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class BtoCServiceImpl implements BtoCService {

    String appId= MerInfoConstant.b2cAppId;

    String appKey=MerInfoConstant.b2cAppKey;

    String digId=MerInfoConstant.digId;

    String cashSn=MerInfoConstant.cashSn;

    String merchantId=MerInfoConstant.opId;

    String termActiveNo=MerInfoConstant.termActiveNo;

    String urlNotify=MerInfoConstant.urlNotify;

    @Autowired
    private PayOrderService payOrderService;

    public static void main(String[] args) {
        // new BtoCServiceImpl().sendPayRequest("80283922245428725211","0.01","2");
        // new BtoCServiceImpl().sendCancelRequest("802835922245428725211","000204");
        System.out.println(new BtoCServiceImpl().sendQueryPayResult("80283922245428725211"));
        // System.out.println(new BtoCServiceImpl().sendQueryPayResult("8888535465487252"));
        // System.out.println(new BtoCServiceImpl().sendQueryPayResult("8088535922465487252111"));
        // System.out.println(new BtoCServiceImpl().sendCancelRequest("8088535922465487252111","000202"));
        // String s="\"errMsg\":\"成功\"";
        // System.out.println(JSONUtil.toBean(s, Map.class));
        // JSONException
    }

    @Override
    public Boolean sendPayRequest(String extOrderNo,String payAmount,String action) {
        // String extOrderNo ="8888"+new SimpleDateFormat("yyyyMMddmmHHssSSS").format(new Date())+ RandomUtils.getRandomNum(7);
        String[] str = UrlConstant.PAY_TYPE.get(action);
        ExtraReq extra = ExtraReq.builder()
                .urlNotify(urlNotify+"?extOrderNo="+extOrderNo+"-1"+action)
                .tradeNo(extOrderNo)
                .digId(digId)
                .cashSn(cashSn)
                .opId(merchantId)
                .reserveInfo("test").build();           // 备注信息，选填
        PosReq pos = PosReq.builder()
                .appName(str[1])
                .transId(str[2]).build();
        TransDataReq transData = TransDataReq.builder()
                .amt(String.valueOf(new BigDecimal(payAmount).multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP)))
                .appId("c0c83bd5025141e6a84e17174c4d5465")
                .isNeedPrintReceipt("false")
                .extOrderNo(extOrderNo)
                .extToUlink("true").build();
        if (action.equals("3")){
            transData.setIsNeedPrintReceipt("true");
        }
        pos.setTransData(transData);
        BtoCPayReq btoCPayReq = BtoCPayReq.builder()
                .action(str[0])
                .termActiveNo(termActiveNo)
                .extra(extra)
                .pos(pos).build();
        String url = "https://api-mop.chinaums.com/v1/yunmis/pos-pay/action";
        try {
            String respStr = sendPost(url,appId, appKey, JSONUtil.toJsonStr(btoCPayReq).toString());
            log.info("发送请求B扫C交易，响应报文：{}", respStr);
            // if (JSONUtil.toBean(respStr,Map.class).get("errCode").equals("000000")){
            //     Map<String,Integer> map = PayOrderNoConstant.getMap().get("c2b");
            //     if (map==null){
            //         map=new HashMap<>();
            //     }
            //     map.put(extOrderNo+"-"+action,1);
            //     PayOrderNoConstant.getMap().put("b2c",map);
            // }
            return JSONUtil.toBean(respStr,Map.class).get("errCode").equals("000000");
            // return extOrderNo;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Map<String, String> sendQueryPayResult(String extOrderNo) {
        // PayOrder one = payOrderService.getOne(new LambdaQueryWrapper<PayOrder>().eq(PayOrder::getTransNo, extOrderNo));
        // String action = one.getIsBankCar();
        String action="2";
        String[] query = UrlConstant.PAY_QUERY_TYPE.get(action);
        ExtraReq extra = ExtraReq.builder()
                .tradeNo(extOrderNo)
                .digId(digId)
                .cashSn(cashSn)
                .opId(merchantId)
                .reserveInfo("查询交易状态").build();           // 备注信息，选填
        TransDataReq transData = TransDataReq.builder()
                .appId("c0c83bd5025141e6a84e17174c4d5465")
                .isNeedPrintReceipt("true")
                .extOrderNo(extOrderNo)
                .traceNo("000000")
                .isShowDetailPage("true").build();
        if (action.equals("2")){
            transData.setTradeType("useScan");
            transData.setOrderDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        }
        PosReq pos = PosReq.builder()
                .appName(query[1])
                .transId(query[2])
                .transData(transData).build();
        BtoCPayReq btoCPayReq = BtoCPayReq.builder()
                .action(query[0])
                .termActiveNo(termActiveNo)
                .extra(extra)
                .pos(pos).build();
        String json = JSONUtil.toJsonStr(btoCPayReq);
        log.info("主动同步交易状态，请求报文：{}", json);
        String url = "https://api-mop.chinaums.com/v1/yunmis/pos-pay/query-sync";
        JSONObject respStr = null;
        try {
            respStr = new JSONObject(sendPost(url,appId, appKey,json.toString()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        log.info("主动同步交易状态b2c，响应报文：{}", respStr);
        String s = (String) JSONUtil.toBean(respStr, Map.class).get("result");
        if (StringUtils.isNotEmpty(s) && s.contains("\":\"")){
            return JSONUtil.toBean(new JSONObject(s), Map.class);
        }
        return null;
    }

    @Override
    public boolean sendCancelRequest(String extOrderNo, String proofNo) {
        ExtraReq extra= ExtraReq.builder()
                .urlNotify(urlNotify+"?extOrderNo="+extOrderNo+"-5")
                .tradeNo("8888"+new SimpleDateFormat("yyyyMMddmmHHssSSS").format(new Date())+ RandomUtils.getRandomNum(7))
                .digId(digId)
                .cashSn(cashSn)
                .opId(merchantId)
                .reserveInfo("退款").build();// 备注信息，选填
        TransDataReq transData = TransDataReq.builder()
                .appId("c0c83bd5025141e6a84e17174c4d5465")
                .isNeedPrintReceipt("true")
                .extOrderNo(extOrderNo)    //商户流水号
                .useScan("false")
                .tradeType("useScan")
                .orgTraceNo(proofNo).build();    //交易凭证
        PosReq pos = PosReq.builder()
                .appName("公共资源")
                .transId("撤销")
                .transData(transData).build();
        BtoCPayReq btoCPayReq = BtoCPayReq.builder()
                .extra(extra)
                .pos(pos)
                .action("cancel")
                .termActiveNo(termActiveNo).build();
        String url = "https://api-mop.chinaums.com/v1/yunmis/pos-pay/action";
        try {
            String respStr = sendPost(url,appId,appKey, JSONUtil.toJsonStr(btoCPayReq).toString());
            log.info("发送撤掉订单【{}】指令, 执行返回结果为：{}", extOrderNo, respStr);
            return "000000".equals(new JSONObject(respStr).getStr("errCode"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String sendPost(String url,String appId,String appKey, String reqBody) throws Exception {
        String authorization = CounterSignUtils.getOpenBodySig(appId,appKey,reqBody);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Authorization", authorization);
        StringEntity se = new StringEntity(reqBody, "UTF-8");
        se.setContentType("application/json");
        httpPost.setEntity(se);
        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity1 = response.getEntity();
        String resStr = null;
        if (entity1 != null) {
            resStr = EntityUtils.toString(entity1, "UTF-8");
        }
        httpClient.close();
        response.close();
        return resStr;
    }
}
